home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-I386 / SOFTIRQ.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  2KB  |  112 lines

  1. #ifndef __ASM_SOFTIRQ_H
  2. #define __ASM_SOFTIRQ_H
  3.  
  4. #include <asm/atomic.h>
  5. #include <asm/hardirq.h>
  6.  
  7. extern unsigned int local_bh_count[NR_CPUS];
  8.  
  9. #define get_active_bhs()    (bh_mask & bh_active)
  10. #define clear_active_bhs(x)    atomic_clear_mask((x),&bh_active)
  11.  
  12. extern inline void init_bh(int nr, void (*routine)(void))
  13. {
  14.     bh_base[nr] = routine;
  15.     atomic_set(&bh_mask_count[nr], 0);
  16.     bh_mask |= 1 << nr;
  17. }
  18.  
  19. extern inline void remove_bh(int nr)
  20. {
  21.     bh_mask &= ~(1 << nr);
  22.     mb();
  23.     bh_base[nr] = NULL;
  24. }
  25.  
  26. extern inline void mark_bh(int nr)
  27. {
  28.     set_bit(nr, &bh_active);
  29. }
  30.  
  31. #ifdef __SMP__
  32.  
  33. /*
  34.  * The locking mechanism for base handlers, to prevent re-entrancy,
  35.  * is entirely private to an implementation, it should not be
  36.  * referenced at all outside of this file.
  37.  */
  38. extern atomic_t global_bh_lock;
  39. extern atomic_t global_bh_count;
  40.  
  41. extern void synchronize_bh(void);
  42.  
  43. static inline void start_bh_atomic(void)
  44. {
  45.     atomic_inc(&global_bh_lock);
  46.     synchronize_bh();
  47. }
  48.  
  49. static inline void end_bh_atomic(void)
  50. {
  51.     atomic_dec(&global_bh_lock);
  52. }
  53.  
  54. /* These are for the IRQs testing the lock */
  55. static inline int softirq_trylock(int cpu)
  56. {
  57.     if (!test_and_set_bit(0,&global_bh_count)) {
  58.         if (atomic_read(&global_bh_lock) == 0) {
  59.             ++local_bh_count[cpu];
  60.             return 1;
  61.         }
  62.         clear_bit(0,&global_bh_count);
  63.     }
  64.     return 0;
  65. }
  66.  
  67. static inline void softirq_endlock(int cpu)
  68. {
  69.     local_bh_count[cpu]--;
  70.     clear_bit(0,&global_bh_count);
  71. }
  72.  
  73. #else
  74.  
  75. extern inline void start_bh_atomic(void)
  76. {
  77.     local_bh_count[smp_processor_id()]++;
  78.     barrier();
  79. }
  80.  
  81. extern inline void end_bh_atomic(void)
  82. {
  83.     barrier();
  84.     local_bh_count[smp_processor_id()]--;
  85. }
  86.  
  87. /* These are for the irq's testing the lock */
  88. #define softirq_trylock(cpu)    (local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
  89. #define softirq_endlock(cpu)    (local_bh_count[cpu] = 0)
  90. #define synchronize_bh()    barrier()
  91.  
  92. #endif    /* SMP */
  93.  
  94. /*
  95.  * These use a mask count to correctly handle
  96.  * nested disable/enable calls
  97.  */
  98. extern inline void disable_bh(int nr)
  99. {
  100.     bh_mask &= ~(1 << nr);
  101.     atomic_inc(&bh_mask_count[nr]);
  102.     synchronize_bh();
  103. }
  104.  
  105. extern inline void enable_bh(int nr)
  106. {
  107.     if (atomic_dec_and_test(&bh_mask_count[nr]))
  108.         bh_mask |= 1 << nr;
  109. }
  110.  
  111. #endif    /* __ASM_SOFTIRQ_H */
  112.